package com.wzxl.config.redis;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 马浩 mahao@aowlx.onaliyun.com
 * @Package com.wzxl.config.redis
 * @Description: TODO ( redis 配置 )
 * @Date 2018/4/20 10:07
 * @Version V1.0
 */
@Data
@Configuration
@EnableConfigurationProperties
//@ConfigurationProperties(prefix="redis")
@ConditionalOnExpression("${spring.redis.enable}")
public class RedisConfig {

    @Autowired
    private final Environment environment;
    private int database;
    private String host;
    private String password;
    private int port;
    private int maxIdle;
    private int minIdle ;
    private int maxActive ;
    private int maxWait ;
    private String sentinelMaster;
    private String sentinelNodes;

    public RedisConfig(Environment environment){
        this.environment = environment;
        this.database = Integer.parseInt(environment.getProperty("spring.redis.database"));
        this.host = environment.getProperty("spring.redis.host");
        this.password = environment.getProperty("spring.redis.password");

        this.port = Integer.parseInt(environment.getProperty("spring.redis.port"));
        this.maxIdle = Integer.parseInt(environment.getProperty("spring.redis.pool.maxIdle"));
        this.minIdle = Integer.parseInt(environment.getProperty("spring.redis.pool.minIdle"));
        this.maxActive = Integer.parseInt(environment.getProperty("spring.redis.pool.maxActive"));
        this.maxWait = Integer.parseInt(environment.getProperty("spring.redis.pool.maxWait"));
    }
    @Bean
    public JedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
        RedisSentinelConfiguration sentinelConfig = null;
        if (this.getSentinelMaster() != null) {
            sentinelConfig = new RedisSentinelConfiguration();
            sentinelConfig.master(this.getSentinelMaster());
            sentinelConfig.setSentinels(createSentinels(this.getSentinelNodes()));
        }

        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(this.getMaxActive());
        config.setMaxIdle(this.getMaxIdle());
        config.setMinIdle(this.getMinIdle());
        config.setMaxWaitMillis(this.getMaxWait());

        JedisConnectionFactory factory = new JedisConnectionFactory(config);
        factory.setHostName(this.getHost());
        factory.setPort(this.getPort());
        if (this.getPassword() != null) {
            factory.setPassword(this.getPassword());
        }
        factory.setDatabase(this.getDatabase());
        return factory;
    }

    @Bean
    public JedisPool jedisPool() {
        try {
            JedisPool pool = new JedisPool(redisConnectionFactory().getPoolConfig(), host, port);
            return pool;
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Bean
    public RedisOperations<Object, Object> redisTemplate() throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
        template.setConnectionFactory(redisConnectionFactory());
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate() throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory());
        return template;
    }

    private List<RedisNode> createSentinels(String sentinelNodes) {
        List<RedisNode> sentinels = new ArrayList<RedisNode>();
        for (String node : StringUtils.commaDelimitedListToStringArray(sentinelNodes)) {
            try {
                String[] parts = StringUtils.split(node, ":");
                Assert.state(parts.length == 2, "Must be defined as 'host:port'");
                sentinels.add(new RedisNode(parts[0], Integer.valueOf(parts[1])));
            }
            catch (RuntimeException ex) {
                throw new IllegalStateException("Invalid redis sentinel "
                        + "property '" + node + "'", ex);
            }
        }
        return sentinels;
    }
}
